-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Restrict Protected to some heap types.
#6471
Conversation
primitives/core/src/crypto.rs
Outdated
| impl<T: Zeroize> From<T> for Protected<T> { | ||
| fn from(t: T) -> Self { | ||
| #[cfg(feature = "std")] | ||
| impl From<String> for Protected<String> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we not just open this From<T: Zeroize>?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is with type as [u8; N] where zeroize is implemented but for whom Protected would be moving/copying stack memory all around. Typically String and Vec are relatively safe to use (as long as we don't reallocate), otherwhise Box would be safe but the api change a bit for it.
Then it does not change a thing with existing code, it just prevents some misuses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Protected does not implement Copy.
Next point is that you can not implement Drop for Copyable types: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ffa7796c63f95857904cdce1e0a3ebc5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was more refering to moves or memory copy of the stack that result from compiling. But the PR just move this case out to avoid such discussion on the public api.
Another way to handle this could be to add a comment.
tomusdrw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks okay, but really requires a bit of explanations in comments on why we restrict the From implementation.
Why not do Protected<T>(Box<T>) instead? So that we are not restricted to heap-allocated types?
|
I had a first implementation with Box but I remember some slight api difference (at least for the sized array case) and did add a new structure for the Box case. Actually looking at 'secrecy' crate from the author of zeroize, that is exactly the three cases that get covered (box, vec and string). |
|
I think the secrecy crate serves mostly as reminder and grep fodder for whenever you access a secret. Use it directly maybe? I'd wait for rust-lang/rfcs#2859 myself before doing anything else. I think heap vs stack remains unconvincing without further effort, ala mlock, which all sounds like a distraction now. We've an |
|
I'm fine to use |
|
Yes, I suppose more discipline in how substrate handles secrets makes sense. All rust crypto crates use almost exclusively stack for secrets. I doubt any would change this until rust-lang/rfcs#2859 and rust-lang/rfcs#2884 works, and maybe someone needs to figure out mlock from rust too, so optimistically a couple years away. It's rather a different problem in substrate though, so sure.. |
|
Last commit simply replace Protected by SecrecyString. |
RFC co-author here. I'm probably not saying anything you don't already know, but I just want to point out that the RFC is dead in the water so far. The lang team hasn't shown any interest yet (that might change with the new MCP process, but I'm skeptical), and until they do there isn't even a guarantee that the RFC will be officialized as something we want in Rust. So "a couple years away" is indeed optimistic. |
cecton
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is great! But maybe it's best to wait for other reviewers
| impl Drop for KeystoreParams { | ||
| fn drop(&mut self) { | ||
| use sp_core::crypto::Zeroize; | ||
| self.password.zeroize(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we not replace password: Option<StringSecret> to remove this custom implementation of Drop here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It implements FromStr, but structopt complain about to_string not being implemented. Could use a type wrapper, but I am not sure it is worth it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, it is actually the from str error that needed to be display, so no pb.
primitives/core/src/crypto.rs
Outdated
| #[doc(hidden)] | ||
| pub use sp_std::ops::Deref; | ||
| use sp_runtime_interface::pass_by::PassByInner; | ||
| #[doc(hidden)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are both of these exported hidden?
|
@bkchr I did remove the drop on the struct opt parameter, looks better now. |
bkchr
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rename and move the secret string parse function. Otherwise it looks good.
primitives/core/src/crypto.rs
Outdated
| #[cfg(feature = "std")] | ||
| /// Parse a sercret string, returning a displayable error. | ||
| pub fn secrety_string_from_str(s: &str) -> Result<SecretString, String> { | ||
| Ok(std::str::FromStr::from_str(s) | ||
| .map_err(|_e| "Could not get SecretString".to_string())?) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| #[cfg(feature = "std")] | |
| /// Parse a sercret string, returning a displayable error. | |
| pub fn secrety_string_from_str(s: &str) -> Result<SecretString, String> { | |
| Ok(std::str::FromStr::from_str(s) | |
| .map_err(|_e| "Could not get SecretString".to_string())?) | |
| } | |
| /// Parse a sercret string, returning a displayable error. | |
| #[cfg(feature = "std")] | |
| pub fn secret_string_from_str(s: &str) -> Result<SecretString, String> { | |
| std::str::FromStr::from_str(s).map_err(|_e| "Could not get SecretString".to_string()) | |
| } |
And please move this to cli. As we only need this in the cli. Please put it into client/cli/src/params/mod.rs.
|
bot merge |
|
Waiting for commit status... |
|
Head SHA has changed since merge was requested; aborting merge. |
2 similar comments
|
Head SHA has changed since merge was requested; aborting merge. |
|
Head SHA has changed since merge was requested; aborting merge. |
|
bot merge |
|
Waiting for commit status... |
|
@cheme will need a master-merge in order to fix cargo-deny error. |
|
Head SHA has changed since merge was requested; aborting merge. |
|
bot merge |
|
Waiting for commit status... |
This PR restrict
Protectedtypes to some heap types.The goal is to avoid wrongly using
Protectedover some structure on stack.I think this should be enough for current usage, going further will probably lead to write https://github.com/iqlusioninc/crates/tree/develop/secrecy .